import { Vector3 } from "@/utils/Vector3"
import { CustomElement } from "@/js/components/CustomElement"

export interface InputInterface {
    getValue: ()=> unknown
    setValue: (value:unknown)=> void
    bindValue: (target: any, propsName: string, changeCallBack?: (newValue: unknown, oldValue: unknown)=> boolean)=> void
}

export class Input extends CustomElement implements InputInterface{
    constructor(){
        super();
        this.setTag("input");
        this.setAttribute("type","text");
    }

    hint(value:string){
        this.setAttribute("placeholder",value);
        return this;
    }

    setValue(value: unknown){
        switch (this.$el.type) {
            case "checkbox":
                this.$el.checked = value
                break
            default:
                this.$el.value = value
        }
        return this
    }

    getValue(){
        switch (this.$el.type) {
            case "number":
                return Number(this.$el.value)
            case "checkbox":
                return this.$el.checked
            case "color":
                    return this.$el.value
            default:
                return this.$el.value;
        }
    }

    bindValue(target: any, propsName: string, changeCallBack?: (newValue: unknown, oldValue: unknown)=> boolean){
        this.addEventListener("change", ()=>{
            const old = target[propsName]
            const newV = this.getValue()
            if(changeCallBack && !changeCallBack(newV, old)) return
            target[propsName] = newV
        })
    }

    setType(type: string){
        (this.$el as HTMLInputElement).type = type
    }

    placeholder(placeholder: string){
        this.$el.placeholder = placeholder
        return this
    }
}

export class Select extends CustomElement implements InputInterface{
    options: string[] = []
    constructor(){
        super();
        this.setTag("select");
        this.setAttribute("type","text")

        this.maxWidth('100px')
        this.minWidth('100px')
    }

    setOptions(options:string[] = []){
        this.$el.innerHTML = ""
        options.forEach(key=>{
            const option = new CustomElement()
            option.setTag("option")
            option.$el.innerHTML = key
            this.appendChild(option)
        })
    } 

    hint(value:string){
        this.setAttribute("placeholder",value);
        return this;
    }

    setValue(value: unknown){
        switch (this.$el.type) {
            case "checkbox":
                this.$el.checked = value
                break
            default:
                this.$el.value = value
        }
        return this
    }

    getValue(){
        switch (this.$el.type) {
            case "number":
                return Number(this.$el.value)
            case "checkbox":
                return this.$el.checked
            case "color":
                    return this.$el.value
            default:
                return this.$el.value;
        }
    }

    bindValue(target: any, propsName: string, changeCallBack?: (newValue: unknown, oldValue: unknown)=> boolean){
        this.addEventListener("change", ()=>{
            const old = target[propsName]
            const newV = this.getValue()
            if(changeCallBack && !changeCallBack(newV, old)) return
            target[propsName] = newV
        })
    }

    setType(type: string){
        (this.$el as HTMLInputElement).type = type
    }

    placeholder(placeholder: string){
        this.$el.placeholder = placeholder
        return this
    }
}